package com.twang.stock.service.jinyan;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.twang.stock.entity.*;
import com.twang.stock.mapper.*;
import com.twang.stock.dto.BaseRequest;
import com.twang.stock.dto.HistoryStockData;
import com.twang.stock.enmu.UserBusinessTypeEnum;
import com.twang.stock.service.UserService;
import com.twang.stock.task.old.UpdateToDayVol;
import com.twang.stock.utils.date.DateUtils;
import com.twang.stock.utils.date.HolidayCopy;
import com.twang.stock.utils.http.AliHttpUtils;
import org.assertj.core.util.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.MapUtils;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;

@Slf4j
@Service
public class StockInfoService {

    @Resource
    private StockInfoMapper stockInfoMapper;
    @Resource
    private CompanyCodeInfoMapper companyCodeInfoMapper;
    @Autowired
    private HolidayService holidayService;
    @Resource
    private HotTagMapper hotTagMapper;

    @Autowired
    private UpdateToDayVol updateToDayVol;
    @Autowired
    private UserService userService;

    @Resource
    private UserBusinessTypeService userBusinessTypeService;

    @Resource
    private UserBusinessTypeMapper userBusinessTypeMapper;



    public List<StockInfo> queryList(List<String> codeList) {
        List<StockInfo> result = null;
        if (!CollectionUtils.isEmpty(codeList)) {
            Example example = new Example(StockInfo.class);
            example.createCriteria().andIn("code", codeList);
            return result = stockInfoMapper.selectByExample(example);
        } else {
            return result = stockInfoMapper.selectAll();
        }
    }

    public  List<StockInfo> queryByPage(BaseRequest baseRequest) throws Exception {
        User user = userService.getUserByToken();
        UserBusinessType userBusinessType =userBusinessTypeService.getUserBusinessType(user.getId(), UserBusinessTypeEnum.TYPE_HOT_TAG.getCode());
        HotTag record = hotTagMapper.selectByPrimaryKey(userBusinessType.getBusinessId());
        //查询标签关联的权重个个股
//        StockTag stockTag = new StockTag();
//        stockTag.setTagId(record.getId());
//        List<StockTag> stockTagList = stockTagMapper.select(stockTag);
        UserBusinessType param=new UserBusinessType();
        param.setType(UserBusinessTypeEnum.TYPE_STOCK_INFO.getCode());
        param.setUserId(user.getId());
        List<UserBusinessType> userBusinessTypeList = userBusinessTypeMapper.select(param);
        List<StockInfo> stockInfoList = Lists.newArrayList();
        userBusinessTypeList.forEach(item -> {
            CompanyCodeInfo companyCodeInfo = companyCodeInfoMapper.selectByPrimaryKey(item.getBusinessId().intValue());
            StockInfo stockInfo;
            if (holidayService.isWorkDay(HolidayCopy.getRealToday()) && holidayService.isWorkDayTradeTime()) {
                stockInfo = updateToDayVol.querySina(companyCodeInfo);
            } else {
                stockInfo = getStockInfoByDateDESC(companyCodeInfo.getCompanyCode());
            }
            if (null != stockInfo) {
                stockInfoList.add(stockInfo);
            }
        });
        return stockInfoList;
    }

    public String getLastDataNow(String code){
        StockInfo  infp=getLastData(code);
        return infp.getDate();
    }

    public StockInfo getLastData(String code){
        return  stockInfoMapper.getLastData(code);
    }
    public String getLastDate(){
        return  stockInfoMapper.getLastDate();
    }

    public StockInfo queryByDto(StockInfo param) {
        List<StockInfo> list = stockInfoMapper.select(param);
        if (list.size() > 0) {
            log.info(" 历史记录存在  size={} list--->{}",list.size(),JSONObject.toJSONString(list));
            return list.get(0);
        } else {
            return null;
        }
    }

    public int insertOrUpdate(StockInfo stockInfo) {
        StockInfo param = new StockInfo();
        param.setCode(stockInfo.getCode());
        param.setDate(stockInfo.getDate());
        StockInfo history = queryByDto(param);
        if (null == history) {
            return stockInfoMapper.insert(stockInfo);
        }
        return 0;
    }

    public StockInfo selectByPrimkey(StockInfo stockInfo){
       return stockInfoMapper.selectByPrimaryKey( stockInfo);
    }

    /**
     *
     */
    public void sumVolAndPrice() {
      List<StockInfo>  dataInfoList=stockInfoMapper.selectAll();
        //更新分时量
        dataInfoList.forEach(item -> {
            StockInfo param = new StockInfo();
            param.setCode(item.getCode());
            param.setDate(item.getDate());
            item=queryByDto(param);
            //5日
            updatePriceAndVol(item, 5);
            //10
            updatePriceAndVol(item, 10);
            stockInfoMapper.updateByPrimaryKey(item);
        });

    }

    public void updatePriceAndVol(StockInfo item, int day) {
        StockInfoDto param = new StockInfoDto();
        param.setCode(item.getCode());
        param.setCreateTime(item.getCreateTime());
        param.setNum(day - 1);
        if (day == 5) {
            item.setPriceMay5(new BigDecimal(0));
            item.setVolMay5(0);
        }
        if (day == 10) {
            item.setPriceMay10(new BigDecimal(0));
            item.setVolMay10(0);
        }
        //更新MAY-5
        List<StockInfo> listMay = stockInfoMapper.updateSUMVolAndAmount(param);
        listMay.forEach(l -> {
            if (day == 5) {
                item.setPriceMay5(Optional.ofNullable(item.getPriceMay5()).orElse(BigDecimal.ZERO).add(Optional.ofNullable(l.getPrice()).orElse(BigDecimal.ZERO)));
                item.setVolMay5(Optional.ofNullable(item.getVolMay5()).orElse(0) + Optional.ofNullable(l.getVolMay1()).orElse(0));
            }
            if (day == 10) {
                item.setPriceMay10(Optional.ofNullable(item.getPriceMay10()).orElse(BigDecimal.ZERO).add(Optional.ofNullable(l.getPrice()).orElse(BigDecimal.ZERO)));
                item.setVolMay10(Optional.ofNullable(item.getVolMay10()).orElse(0) + Optional.ofNullable(l.getVolMay1()).orElse(0) );
            }
        });
        if (day == 5) {
            item.setPriceMay5((Optional.ofNullable(item.getPriceMay5()).orElse(BigDecimal.ZERO).add(item.getPrice())).divide(new BigDecimal(day), 2, BigDecimal.ROUND_HALF_UP));
            item.setVolMay5((Optional.ofNullable(item.getVolMay5()).orElse(0) + item.getVolMay1()) / day);
        }
        if (day == 10) {
            item.setPriceMay10((Optional.ofNullable(item.getPriceMay10()).orElse(BigDecimal.ZERO).add(item.getPrice())).divide(new BigDecimal(day), 2, BigDecimal.ROUND_HALF_UP));
            item.setVolMay10((Optional.ofNullable(item.getVolMay10()).orElse(0) + item.getVolMay1()) / day);
        }
    }

    /**
     * @param startDate 2021-03-01
     * @param endDate   2021-03-30
     */
    public void queryHistoryData(String startDate, String endDate, String code) {
        CompanyCodeInfo param=new CompanyCodeInfo();
        if(!StringUtils.isEmpty(code)){
            param.setCompanyCode(code);
        }
        List<CompanyCodeInfo> listCode = companyCodeInfoMapper.select(param);
        AtomicInteger count= new AtomicInteger();
        listCode.forEach(l -> {
            try {
                Thread.sleep(6000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            String host = "http://stock.market.alicloudapi.com";
            String path = "/sz-sh-stock-history";
            String method = "GET";
            String appcode = "d9c1041a8106420593a6c0fa11e2d8fd";
            Map<String, String> headers = new HashMap<String, String>();
            //最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105
            headers.put("Authorization", "APPCODE " + appcode);
            Map<String, String> querys = new HashMap<String, String>();
            querys.put("begin", startDate);
            querys.put("code", l.getCompanyCode());
            querys.put("end", endDate);
            String result = "";
            try {
                /**
                 * 重要提示如下:
                 * HttpUtils请从
                 * https://github.com/aliyun/api-gateway-demo-sign-java/blob/master/src/main/java/com/aliyun/api/gateway/demo/util/HttpUtils.java
                 * 下载
                 *
                 * 相应的依赖请参照
                 * https://github.com/aliyun/api-gateway-demo-sign-java/blob/master/pom.xml
                 */
                HttpResponse response = AliHttpUtils.doGet(host, path, method, headers, querys);
                // System.out.println(response.toString());
                //获取response的body
                result = EntityUtils.toString(response.getEntity());
                // System.out.println(result);
            } catch (Exception e) {
                e.printStackTrace();
            }
            //
            count.getAndIncrement();
            log.info(" 第{} 次调用接口 code={}  info={}",count, l.getCompanyCode(), result);
            if (!StringUtils.isEmpty(result)) {
                result = MapUtils.getString(jsonStringToMap(String.valueOf(result)), "showapi_res_body");
                String titless = MapUtils.getString(jsonStringToMap(String.valueOf(result)), "list");
                List<HistoryStockData> list = JSONObject.parseArray(titless, HistoryStockData.class);
                list.forEach(item -> {
                    StockInfo info = new StockInfo();
                    info.setCode(item.getMarket() + item.getCode());
                    info.setDate(item.getDate().replace("-", ""));
                    info.setPrice(new BigDecimal(item.getClosePrice()));
                    info.setPriceMax(new BigDecimal(item.getMaxPrice()));
                    info.setPriceMin(new BigDecimal(item.getMinPrice()));
                    info.setVolMay1(Integer.valueOf(item.getTradeNum()));
                    info.setVolMay1Avg(info.getVolMay1() / 240);
                    info.setCreateTime(DateUtils.getDate(item.getDate()));
                    insertOrUpdate(info);
                });
            }
        });
    }

    /**
     * @param
     * @return
     * @throws
     * @Description: JSONString转Map
     * @author liushiwei
     * @date 2018/9/27 15:42
     */
    private static Map<String, Object> jsonStringToMap(String json) {
        //String转成JSONObject形式
        JSONObject jsonArray = JSONObject.parseObject(json);
        Map<String, Object> param = JSONObject.parseObject(jsonArray.toJSONString(), new TypeReference<Map<String, Object>>() {
        });
        return param;
    }

    /**
     * 获取当前时间上一个交易日数据
     * @param code
     * @param date
     * @return
     */
    public StockInfo getCode(String code, String date) {
        StockInfoDto param = new StockInfoDto();
        param.setCode(code);
        param.setDate(date);
        return stockInfoMapper.selctScondData(param);
    }

    public StockInfo getCodeToday(String code, String date) {
        StockInfoDto param = new StockInfoDto();
        param.setCode(code);
        param.setDate(date);
        return stockInfoMapper.selectOne(param);
    }

    /**
     * 获取最新的数据
     * @param cdoe
     * @return
     */
    public StockInfo getStockInfoByDateDESC(String cdoe) {
        Example example = new Example(StockInfo.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("code", cdoe);
        example.orderBy("date").desc();
        List<StockInfo> stockInfoList=stockInfoMapper.selectByExample(example);
        if(CollectionUtils.isEmpty(stockInfoList)){
            return null;
        }
        return stockInfoList.get(0);
    }

}
